Matlab下求解方程的常规方法指南 您所在的位置:网站首页 evos首发限量版 白色 Matlab下求解方程的常规方法指南

Matlab下求解方程的常规方法指南

2023-07-16 16:16| 来源: 网络整理| 查看: 265

实验室的同学在科研中遇到了求解超越方程时结果精度控制的问题,力求给出精确解。阿伟由此学习了 Matlab 中求解方程的一般方法。本文介绍了 solve( ),fsolve( ),fzero( ) 这三个解方程常规方法,以及给出了解复杂超越方程的方法示例。

一. solve( )函数

Matlab 中求解简单方程的最一般方法是使用 solve 函数,话不多说,直接上例子。

(A) 求解一元方程

例:求解$$x^2-7x+12=0$$代码为

123syms x;eq = x^2 - 7*x + 12;s = solve(eq,x)

结果为

123s= 3 4

注:(1) syms x; 这一句是声明参数。 (2) s = solve(eq,x) 这里声明了以x为变量求解。同时注意到结尾没加分号,这是为了直接在命令行看到结果。

(B) 求解二元方程

例:求解$$ax^2+by+c=0$$$$ax+2y=4$$

其中 x, y 是变量。代码为

1234syms a b c y x;eq1 = a*x^2 + b*y +c;eq2 = a*x + 2*y -4;[x,y] = solve([eq1,eq2],[x,y])

结果为

1234567x = ((a*b)/4 - (-(a*(- a*b^2 + 32*b + 16*c))/16)^(1/2))/a ((a*b)/4 + (-(a*(- a*b^2 + 32*b + 16*c))/16)^(1/2))/ay = (-(a*(- a*b^2 + 32*b + 16*c))/16)^(1/2)/2 - (a*b)/8 + 2 2 - (-(a*(- a*b^2 + 32*b + 16*c))/16)^(1/2)/2 - (a*b)/8

注:(1) 最后 x,y 分别会输出两个结果,分别对应 x1,x2 与 y1,y2。 (2) 多元方程可仿照求解。

二. fsolve( )函数

fsolve( ) 函数通常用于数值求方程或方程组的解,更常用于求解非线性方程组。

(A) 语法1x = fsolve(fun,x0,options) 1[x,fval,exitflag] = fsolve(fun,x0,options)

其中,fun 是待求解方程;x0 是初值(初值通常设定在解的附近,求解器其实是在给出的初值附近求出方程的局部最优解);options 是一些设定要求,可以用 optimset 函数来实现;exitflag 用以描述出口条件 (exit condition),exitflag 返回的数字及其含义分别是1 fsolve converged to a root.2 Change in X too small.3 Change in residual norm too small.4 Computed search direction too small.0 Too many function evaluations or iterations.-1 Stopped by output/plot function.-2 Converged to a point that is not a root.-3 Trust region radius too small (Trust-region-dogleg).从上面看,当 exitflag 是 1 的时候是最理想的结果,2,3 也可接受,负数则偏差太大或直接错误。

(B) 求解一元方程

例:求解$$sin(x)-0.5=0$$代码为

方法一:直接求解,代码如下 1x = fsolve(@(x)sin(x)-0.5,[1 3])

结果为

12x = 0.5236 2.6180 方法二:建立 .m 文件(对于函数比较长或者比较复杂的情况尤其建议如此)

保存以 myfun.m 为名的 .m 文件

123function f = myfun(x)f = sin(x) - 0.5;end

然后调用函数

1x = fsolve(@myfun,[1 3])

结果为

12x = 0.5236 2.6180 如果在方法二调用函数时使用以下代码 1[x,fval,exitflag] = fsolve(@myfun,[1 3 8 9])

结果为

123456789x = 0.5236 2.6180 8.9012 8.9012fval = 1.0e-09 * -0.1387 -0.0000 -0.0000 -0.0000exitflag = 1

其中 fval 为真实值与拟合值之间的差,从结果来看是非常理想的。

(C) 求解二元方程

例:求下列非线性方程组在 (0.5,0.5) 附近的数值解

$$x-0.6sin(x)-0.3cos(y)=0$$$$y-0.6cos(x)+0.3sin(y)=0$$

代码为myfun.m

123456function q = myfun(p)x = p(1);x = p(2);q(1) = x - 0.6*sin(x) - 0.3*cos(y);q(2) = y - 0.6*cos(x) + 0.3*sin(y);end

然后调用函数

1x = fsolve('myfun',[0.5,0.5],optimset('Display','off'))

结果为

12x = 0.6354 0.3734

注意:调用函数语句输入 ‘myfun’,要加单引号,不按照这么输入可能会报错。

或者调用函数语句也可以写成

1x = fsolve(@myfun,[0.5,0.5],optimset('Display','off')) 三. fzero( )函数(A) 语法

Matlab中提供了一个 fzero( ) 函数,可以用来求单变量非线性方程的根。该函数的调用格式为

1x = fzero('fname',x0,tol,trace)

其中 fname 是待求根的函数文件名。x0 为搜索的起点,一个函数可能有多个根,但 fzero 函数只给出离 x0 最近的那个根。tol 控制结果的相对精度,默认时取 tol=eps。trace指迭代信息是否在运算中显示,为1时显示,为0时不显示,默认时取 trace=0。

(B) 示例

例:求解下列方程在 x=0.5 附近的根$$x^2-10x+2=0$$代码为myfun.m

123function f = myfun(x)f = x^2 - 10*x +2;end

然后调用函数

1x = fzero('myfun',0.5)

结果为

12x = 0.2042 四. 小结:solve( ) 和 fsolve( ) 的比较

(A) solve 一般解线性方程,而 fsolve 一般解非线性方程。(B) solve 函数的局限性:对于非多项式方程,只能求出一个解,对于稍许复杂的方程,求解结果出现很大误差,求解复杂的多项式方程时,可能会产生错误的求解结果,可能无法求解,且非常耗时,求解超越方程时,只能返回一个解或者可能返回错误解。(C) fsolve 函数小结:fsolve 可以求解方程(组) 的实数根和复数根,fsolve 采用迭代的数值算法,速度快,给定不同的初值,可以求得不同的根(局部寻根),初值给的不好,可能导致求解失败。关于初值如何给定的问题(1) 一元/ 二元方程(组),通过图解法,可以得到根的个数,并粗略地估计出根的值,用做 fsolve 的初值。(2) 根据方程组中变量的实际意义,合适地给出初值。例如,时间/ 长度/ 质量等物理量,应该大于 0。(3) 通过更多的练习和经验积累,自然会见多识广。

五. 非一般方法示例

Matlab 中使用 solve( ),fsolve( ),fzero( ),可以求解一般的方程或方程组,但是当求解较为复杂的超越方程时,上述方法大概率是得不出理想结果的。对于复杂的超越方程的求解,阿伟同学建议花点时间写一套完整的算法。这里给出了 Matlab 中一些全局优化相关函数示例。

(A) 约束条件的粒子群求解器: particleswarm( )

Matlab 中提供了粒子群优化算法 particleswarmx = particleswarm(fun,nvars) attempts to find a vector x that achieves a local minimum of fun. nvars is the dimension (number of design variables) of fun.大意是:粒子群优化算法目标是求解函数的局部最小值。

语法12345x = particleswarm(fun,nvars) x = particleswarm(fun,nvars,lb,ub)x = particleswarm(fun,nvars,lb,ub,options)x = particleswarm(problem)[x,fval,exitflag,output] = particleswarm(___)

x = particleswarm(fun,nvars) attempts to find a vector x that achieves a local minimum of fun. nvars is the dimension (number of design variables) of fun.

x = particleswarm(fun,nvars,lb,ub) defines a set of lower and upper bounds on the design variables, x, so that a solution is found in the range lb ≤x≤ ub.

x = particleswarm(fun,nvars,lb,ub,options) minimizes with the default optimization parameters replaced by values in options. Set lb = [] and ub = [] if no bounds exist.

x = particleswarm(problem) finds the minimum for problem, where problem is a structure.

[x,fval,exitflag,output] = particleswarm(___), for any input arguments described above, returns:

A scalar fval, which is the objective function value fun(x) A value exitflag describing the exit condition A structure output containing information about the optimization process (B) 创建优化问题结构算法:createOptimProblem( )

Matlab 中提供了创建优化问题结构算法:createOptimProblem

语法12problem = createOptimProblem('solverName')problem = createOptimProblem('solverName','ParameterName',ParameterValue,...)

problem = createOptimProblem('solverName') creates an empty optimization problem structure for the solverName solver.

problem = createOptimProblem('solverName','ParameterName',ParameterValue,...) accepts one or more comma-separated parameter name/value pairs. Specify ParameterName inside single quotes.

solverName: Name of the solver. For a GlobalSearch problem, use ‘fmincon’. For a MultiStart problem, use ‘fmincon’, ‘fminunc’, ‘lsqcurvefit’ or ‘lsqnonlin’.

(C) 寻找全局最小值: GlobalSearch( )

A GlobalSearch object contains properties (options) that affect how run repeatedly runs a local solver to generate a GlobalOptimSolution object. When run, the solver attempts to locate a solution that has the lowest objective function value.大意是:GlobalSearch( ) 算法功能是在全局范围内寻找目标函数最小值。

语法1234gs = GlobalSearchgs = GlobalSearch(Name,Value)gs = GlobalSearch(oldGS,Name,Value)gs = GlobalSearch(ms)

gs = GlobalSearch creates gs, a GlobalSearch solver with its properties set to the defaults.

gs = GlobalSearch(Name,Value) sets properties using name-value pairs.

gs = GlobalSearch(oldGS,Name,Value) creates a copy of the oldGS GlobalSearch solver, and sets properties using name-value pairs.

gs = GlobalSearch(ms) creates gs, a GlobalSearch solver, with common property values from the ms MultiStart solver.

使用 run( ) 函数运行 GlobalSearch( )1x = run(gs, problem);

该命令是运行 GlobalSearch 以找到问题的解决方案或多个本地解决 problem 方案。

1[x,fval] = run(gs, problem);

该命令在运行 GlobalSearch 后,还会返回目标函数值在 x 点出找到的最佳值。

(D) 示例

以下方程$$F_1(x)=(x_1+1)(10-x_1)\frac{1+x^2_{2}}{1+x^2_{2}+x_2}$$$$F_2(x)=(x_2+2)(20-x_2)\frac{1+x^2_{1}}{1+x^2_{1}+x_1}$$

该方程有四组解,分别是

12X = (-1,-2) (10,-2) (-1,20) (10,20)

试用 GlobalSearch 方法得出 (-1,-2) 这组解

代码为

1234567891011121314151617181920function mainlb = [-inf -inf]; ub = [0 0]; %限定求解范围x0 = particleswarm(@(x)sum(myfun(x).^2),2,lb,ub); %利用 particleswarm 得到一个搜索初值opts = optimoptions(@fmincon,'Algorithm','interior-point','Display','off');problem = createOptimProblem('fmincon','x0',x0,'objective',@(x)0,'lb',lb,'ub',ub,'nonlcon',...@(x)constrain(x,@myfun));gs = GlobalSearch;[x,~,exitflag] = gs.run(problem) %全局搜索endfunction F = myfun(x)F(1) = (x(1)+1)*(10-x(1))*(1+x(2)^2)/(1+x(2)^2+x(2));F(2) = (x(2)+2)*(20-x(2))*(1+x(1)^2)/(1+x(1)^2+x(1));end% fmincon 的非线性约束function [c ceq] = constrain(x,f)ceq = f(x);c =[];end

运行结果为

123456789101112Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.GlobalSearch stopped because it analyzed all the trial points.All 8 local solver runs converged with a positive local solver exit flag.x = -1.0000 -2.0000exitflag = 1


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有